package au.csiro.nt.psdp.dao.impl;

import au.csiro.nt.psdp.actions.util.RolePermissionsUtil;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UserDetailsService;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.appfuse.dao.hibernate.GenericDaoHibernate;
import org.hibernate.FlushMode;
import org.hibernate.Session;

import java.util.*;

import au.csiro.nt.psdp.model.User;
import au.csiro.nt.psdp.dao.UserDao;

/**
 * This class interacts with Spring's HibernateTemplate to save/delete and
 * retrieve User objects.
 *
 * @author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
 *         Modified by <a href="mailto:dan@getrolling.com">Dan Kibler</a>
 *         Extended to implement Acegi UserDetailsService interface by David Carter david@carter.net
 *         Modified by <a href="mailto:bwnoll@gmail.com">Bryan Noll</a> to work with
 *         the new BaseDaoHibernate implementation that uses generics.
 */
public class UserDaoImpl extends GenericDaoHibernate<User, Long> implements UserDao, UserDetailsService
{

    public UserDaoImpl()
    {
        super(User.class);
    }

    /**
     * @see org.appfuse.dao.UserDao#getUsers()
     */
    public List<User> getUsers()
    {
        return getHibernateTemplate().find("from User u order by upper(u.username)");
    }
    public List<User> getUsers(String userName)
    {          System.out.println("username: " + userName);
        return getHibernateTemplate().find("from User where username like " + " ? " + "" , userName + "%" );
    }
    public List<User> getInstructors()
    {
//        List<User> users = getHibernateTemplate().find("from User u where u.user_id in (select user_id from user_role where role_id=2)");
        List<User> users = getHibernateTemplate().find("from User u order by upper(u.username)");
        Iterator iterator = users.iterator();
        User user;
        while (iterator.hasNext()){
            //user = (User)iterator.next();
            if(!RolePermissionsUtil.isOrganisation((User)iterator.next())){
                //System.out.println("remove:" + user.getUsername());
                iterator.remove();
            }
        }
        return users;
           
    }

    /**
     * @see org.appfuse.dao.UserDao#saveUser(org.appfuse.model.User)
     */
    public User saveUser(final User user)
    {
        log.debug("user's id: " + user.getId());
//        getHibernateTemplate().saveOrUpdate(user);
        // necessary to throw a DataIntegrityViolation and catch it in UserManager
//        getHibernateTemplate().flush();

        Session session = getHibernateTemplate().getSessionFactory().getCurrentSession();
        session.beginTransaction();
        session.setFlushMode(FlushMode.AUTO);

        session.save(user);


        session.flush();
        session.getTransaction().commit();
        return user;
    }

    /**
     * Overridden simply to call the saveUser method. This is happenening
     * because saveUser flushes the session and saveObject of BaseDaoHibernate
     * does not.
     */
    @Override
    public void save(User user)
    {
        this.saveUser(user);
    }

    /**
     * @see org.acegisecurity.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
     */
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
    {
        List users = getHibernateTemplate().find("from User where username=?", username);
        if (users == null || users.isEmpty())
        {
            throw new UsernameNotFoundException("user '" + username + "' not found...");
        }
        else
        {
            return (UserDetails) users.get(0);
        }
    }

    public void removeUser(User user)
    {
     //from User where username like '" + " ? " + "'"    
         List users = getHibernateTemplate().find("from User where username like " + " ? " + "" , user.getUsername()+ "%");
                 if (users != null )
        {
            for (int i =0; i< users.size(); i++){
                Session session = getHibernateTemplate().getSessionFactory().getCurrentSession();
                try {
                    
                    session.beginTransaction();
                    session.setFlushMode(FlushMode.AUTO);
                    System.out.println("User information: "  + ((User)users.get(i)).getUsername());
                    session.delete((User)users.get(i));
                    session.flush();
                    session.getTransaction().commit();
                } catch (Exception e){
                    session= null;
                }
            }
        }
    }
}
